home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 09 - 1993 / 09.06 Jun 93 / Dragging Lists / LtoLDragUnit.p < prev    next >
Encoding:
Text File  |  1993-01-06  |  6.1 KB  |  260 lines  |  [TEXT/MPS ]

  1. UNIT LToLDragUnit;
  2.  
  3. INTERFACE
  4.  
  5. USES
  6.     MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf;
  7.  
  8.     PROCEDURE InitLtoLDrag;
  9.     {Initialize the unit's global variables}
  10.  
  11.     PROCEDURE SetDragEnvironment (DestDialog :
  12.         DialogPtr);
  13.     {Call this procedure when you switch dialogs}
  14.  
  15.     FUNCTION LtoLClickProc : BOOLEAN;
  16.     {The 'item dragging' Clickproc}
  17.  
  18. CONST
  19.     kDragToOwnList        =    $01;
  20.     kDragToOtherList    =    $02;
  21.     kDragOutside            =    $04;
  22.  
  23. {$i DragUnitUserDefs.i}
  24.  
  25. IMPLEMENTATION
  26.     
  27. VAR
  28.     gSourceList        : ListHandle;
  29.     gDestLists         : ARRAY [1..10] OF ListHandle;
  30.     gNumDestLists    : Integer;
  31.     gTheDialog         : DialogPtr;
  32.     gDragStyle         : Integer;
  33.     AnchorDefined    : BOOLEAN;
  34.     AnchorPoint, 
  35.     OldPoint,
  36.     NextPoint         : Point;
  37.  
  38. CONST
  39.     kInvalidDrag    =    $8000;
  40.     kMaxDestLists    =    10;
  41.  
  42. {The following routines should be defined by}
  43. {the programmer in DragUnitUserProcs.i}
  44. PROCEDURE DragToDestAction (SourceList :     ListHandle; SourceCell : Point; DestList :
  45.     ListHandle; DestCell : Point);    FORWARD;
  46. PROCEDURE DragToSourceAction (SourceList :
  47.     ListHandle; SourceCell : Point; DestList :
  48.     ListHandle; DestCell : Point);        FORWARD;
  49. PROCEDURE BadDragAction (SourceList :
  50.     ListHandle; SourceCell : Point);    FORWARD;
  51. PROCEDURE DragOutsideAction (SourceList :
  52.     ListHandle; SourceCell : Point);    FORWARD;
  53. PROCEDURE SetSourceDestLists (ClickPt : Point);
  54.     FORWARD;
  55.  
  56. {------------------------------------------------}
  57.  
  58. PROCEDURE InitLtoLDrag;
  59. VAR
  60.     i : Integer;
  61. BEGIN
  62.     SetPt(AnchorPoint, 0, 0);
  63.     AnchorDefined := FALSE;
  64.     OldPoint := AnchorPoint;
  65.     NextPoint := AnchorPoint;
  66.     gSourceList := NIL;
  67.     FOR i := 1 TO kMaxDestLists DO
  68.         gDestLists[i] := NIL;
  69.     gNumdestLists := 0;
  70. END;
  71.  
  72. {------------------------------------------------}
  73.  
  74. PROCEDURE SetDragEnvironment (DestDialog :
  75.     DialogPtr);
  76. BEGIN
  77.     gTheDialog := DestDialog;
  78. END;
  79.  
  80. {------------------------------------------------}
  81.         
  82. FUNCTION FindCell(VAR Selected_Cell :
  83.     Point; TheList : ListHandle) : BOOLEAN;
  84. {Return the currently selected cell in TheList}
  85. BEGIN
  86.     SetPt(Selected_Cell, 0, 0);
  87.     FindCell:= LGetSelect(TRUE,
  88.         Selected_Cell, TheList);
  89. END;     
  90.  
  91. {------------------------------------------------}
  92.  
  93. FUNCTION CanDragToSelf : BOOLEAN;
  94. BEGIN
  95.     CanDragToSelf := BAND(kDragToOwnList,
  96.         gDragStyle) > 0;
  97. END;
  98.  
  99. {------------------------------------------------}
  100.  
  101. FUNCTION CanDragToOther : BOOLEAN;
  102. BEGIN
  103.     CanDragToOther := BAND(kDragToOtherList,
  104.         gDragStyle) > 0 
  105. END;
  106.  
  107. {------------------------------------------------}
  108.  
  109. FUNCTION CanDragOutside : BOOLEAN;
  110. BEGIN
  111.     CanDragOutside := BAND(kDragOutSide, gDragStyle)
  112.                                             > 0;
  113. END;
  114.  
  115. {------------------------------------------------}
  116.  
  117. PROCEDURE DragProc;
  118. VAR
  119.     MPos             : Point;
  120.     WhichCell    : Point;
  121.     TempRect        : Rect;
  122.     i                    : Integer;
  123.  
  124.     PROCEDURE CheckList(TheList:ListHandle);
  125.     BEGIN
  126.         IF TheList = NIL THEN
  127.             EXIT(CheckList);
  128.         TempRect := TheList^^.rView;
  129.         IF PtInRect(MPos, TempRect) THEN
  130.         BEGIN
  131.             MPos.v := ((MPos.v - TempRect.Top) DIV 
  132.                 TheList^^.CellSize.v) +
  133.                 TheList^^.Visible.Top;
  134.             MPos.h := 0;
  135.             IF FindCell(WhichCell, TheList) THEN
  136.             BEGIN
  137.                 IF NOT(EqualPt(WhichCell, MPos)) THEN
  138.                 BEGIN
  139.                     LSetSelect (FALSE, WhichCell, TheList);
  140.                     LSetSelect (TRUE, MPos, TheList);
  141.                 END;    {equalpt}
  142.             END    {FindCell}
  143.             ELSE
  144.                 LSetSelect (TRUE, MPos, TheList);
  145.         END;    {PtInRect}
  146.     END;
  147.  
  148. BEGIN
  149.     GetMouse(MPos);
  150.     IF CanDragToSelf THEN
  151.       CheckList(gSourceList);
  152.  
  153.     IF CanDragToOther THEN
  154.         FOR i := 1 TO gNumDestLists DO
  155.             CheckList(gDestLists[i]);
  156. END;
  157.  
  158. FUNCTION  LtoLClickProc : BOOLEAN;
  159. VAR
  160.     R                         : RgnHandle;
  161.     OldState         : PenState;
  162.     TT, L                    : LongInt;
  163.     B                         : BOOLEAN;
  164.     DestCell, SourceCell, 
  165. SelectedCell    : Point;
  166.     CellRect         : Rect;
  167.     LimitRect, SlopRect : Rect;
  168.     i                         : Integer;
  169.     TempRect         : Rect;
  170. BEGIN
  171.     LtoLClickProc := TRUE;    
  172.     IF NOT(AnchorDefined) THEN
  173.     BEGIN
  174.         AnchorDefined := TRUE;    {store the point where}
  175.         GetMouse(AnchorPoint);    {we initially clicked }
  176.         {Call this to set the lists we can drag to}
  177.         SetSourceDestLists (AnchorPoint);
  178.         EXIT(LtoLClickProc);    {exit here so that}
  179.     END    {the cell will be hilighted}
  180.     ELSE
  181.       AnchorDefined := FALSE;
  182.     
  183.     IF FindCell(SourceCell, gSourceList) THEN
  184.     BEGIN
  185.         LRect(CellRect, SourceCell, gSourceList);
  186.         IF CanDragToSelf & NOT(CanDragToOther) THEN
  187.         BEGIN
  188.             SetRect(LimitRect, gSourceList^^.rView.Left +
  189.                             (AnchorPoint.h - CellRect.Left),
  190.                             gSourceList^^.rView.Top +
  191.                             (AnchorPoint.v - CellRect.Top),
  192.                             gSourceList^^.rView.Right -
  193.                             (CellRect.Right - AnchorPoint.h),
  194.                             gSourceList^^.rView.Bottom -                                 (CellRect.Bottom - AnchorPoint.v));
  195.             SlopRect := gSourceList^^.rView;
  196.         END
  197.         ELSE
  198.         BEGIN
  199.             SetRect(LimitRect, gTheDialog^.PortRect.Left
  200.                             + (AnchorPoint.h - CellRect.Left),
  201.                             gTheDialog^.PortRect.Top + 
  202.                             (AnchorPoint.v - CellRect.Top),
  203.                             gTheDialog^.PortRect.Right - 
  204.                             (CellRect.Right - AnchorPoint.h),
  205.                             gTheDialog^.PortRect.Bottom - 
  206.                             (CellRect.Bottom - AnchorPoint.v));
  207.             SlopRect := gTheDialog^.PortRect;
  208.         END;
  209.         {now that we have selected a cell, use}
  210.         {DragGrayRgn to drag it around}
  211.         InsetRect (SlopRect, -1, -1);
  212.         R := NewRgn;
  213.         RectRgn(R, CellRect);
  214.         L := DragGrayRgn(R, AnchorPoint, LimitRect,
  215.             SlopRect, noConstraint, @DragProc);
  216.         IF HiWord(L) = kInvalidDrag THEN 
  217.           BadDragAction (gSourceList, SourceCell)
  218.         ELSE
  219.         BEGIN
  220.             DestCell.v := AnchorPoint.v + HiWord(L);
  221.             DestCell.h := AnchorPoint.h + LoWord(L);
  222.             IF PtInRect(DestCell, gSourceList^^.rView) &
  223.                     CanDragToSelf THEN
  224.             BEGIN
  225.                 IF FindCell(DestCell, gSourceList) THEN
  226.                     DragToSourceAction (gSourceList,
  227.                         SourceCell, gSourceList, DestCell);
  228.             END
  229.             ELSE
  230.             BEGIN
  231.                 IF CanDragToOther THEN
  232.                 BEGIN
  233.                     FOR i := 1 TO gNumDestLists DO
  234.                         BEGIN
  235.                             IF (gDestLists[i] <> NIL) &
  236.                                 (PtInRect(DestCell,
  237.                                 gDestLists[i]^^.rView)) &
  238.                                 FindCell(DestCell, gDestLists[i])
  239.                             THEN
  240.                                 BEGIN
  241.                                     DragToDestAction (gSourceList,
  242.                                         SourceCell, gDestLists[i],
  243.                                         DestCell);
  244.                                     EXIT(LtoLClickProc);
  245.                                 END;    {if FindCell}
  246.                         END;    {for}
  247.                 END;    {if CanDragToOther}
  248.                 
  249.                 IF CanDragOutSide THEN
  250.                     DragOutsideAction (gSourceList,
  251.                                                                      SourceCell);
  252.             END;    {else}
  253.         END;    {if not kinvaliddrag}
  254.     END;    {FindCell}
  255. END;    {LtoLClickProc}
  256.  
  257. {$i DragUnitUserProcs.i}
  258. END.
  259.  
  260.